#include "cviewer.h"

#include <buola/scene/geodes/ccube.h>
#include <buola/scene/geodes/cpointcloud.h>
#include <buola/scene/cperspectivecamera.h>
#include <buola/scene/transform/crttransform.h>
#include <buola/scene/controllers/ccameracontroller.h>
#include <buola/app/ceventloop.h>
#include <buola/gui/ctoolkit.h>
#include <buola/image/cgc.h>
#include <buola/bbox/functions.h>

namespace buola { namespace bviewer {

CViewer::CViewer()
    :   iCloud(std::bind(&CViewer::OnCloud,this,_1))
{
    scene::PScene lScene=new scene::CScene;
    
    scene::PCube lCube=new scene::CCube;
    scene::PRTTransform lTransform=new scene::CRTTransform(mat::CQuat_d(),{0,0,5});
    lCube->AttachTo(lTransform);
    lScene->World()->AddChild(lTransform);

    mCloud=new scene::CPointCloud();
    lScene->World()->AddObject(mCloud);

    scene::PPerspectiveCamera lCamera=new scene::CPerspectiveCamera;
    lCamera->SetFOV(2*atan2(240.0,525.0));
    lCamera->SetClipping(0.1,50.0);
    lCamera->LookAt({0,0,1},{0,0,0},{0,-1,0});

    mSceneView=new scene::CSceneView;
    mSceneView->SetCamera(lCamera);
    mSceneView->AddScene(lScene);
    mSceneView->AddController(new scene::CCameraController(lCamera));

    Place(mSceneView);

    auto lProxy=bbox::get_service("/org/buola/bkinect");
    bbox::link(lProxy["oCloud"],iCloud);
}

void CViewer::OnLayout()
{
    mSceneView->Map({0,0},Size());
}

void CViewer::OnCloud(cvi::CCloud_rgb8&& pCloud)
{
    lock_guard<recursive_mutex> lLock(get_main_event_loop().GetMutex());

    mCloud->SetCloud(std::move(pCloud));
    mSceneView->Refresh();
}

/*namespace bviewer*/ } /*namespace buola*/ }

using namespace buola;

int main(int pNArgs,char **pArgs)
{
    buola_init(pNArgs,pArgs);
    gui::get_toolkit()->GetOpenGLGC()->MakeCurrent();
    bviewer::CViewer lWindow;
    lWindow.Map(CSize_d(800,600));
    buola_main_loop();
    return buola_finish();
}
